//
//  ClientComboBoxController.m
//  ProcessTimeBudget
//
//  Created by isempty.chiu on 2010/9/8.
//  Copyright 2010 LifeMotion. All rights reserved.
//

#import "EventController.h"
#import "AppController.h"
#import "EventItem.h"
#import "ProcessMonitor.h"
#import "ProcessRecordTableController.h"
#import "SummaryController.h"
#import "CommonFunc.h"

@implementation EventController
@synthesize eventComboBox;
@synthesize eventRunningLabel;
@synthesize eventAdd;
@synthesize eventDel;

EventController	*eventController = nil;
+(EventController*)sharedController
{
	return eventController;
}

-(id)init
{
	// Assign self to value returned by super's designated initializer 
	// Designated initializer for NSObject is init 	
	if(eventController != nil)
		return nil;
	self = [super init];	
	if(self)
	{
		eventList_ = [[NSMutableArray alloc] init];
	}
	
	eventController = self;
	
	//Notification
	[[NSNotificationCenter defaultCenter] addObserver:self
											 selector:@selector(ProcMonitorActiveChanged)
												 name:@"ActiveChanged" object:[ProcessMonitor sharedProcMonitor]];	

	[[NSNotificationCenter defaultCenter] addObserver:self
											 selector:@selector(checkEventButtonStatus)
												 name:@"EventCountChanged" object:nil];	
	
	return self;
}

-(void) dealloc
{
	//KVO
	[[ProcessMonitor sharedProcMonitor] removeObserver:self forKeyPath:@"RunningTime"];
	[[SummaryController sharedController] removeObserver:self forKeyPath:@"CandidateEventName"];
	
	//Notification
	[[NSNotificationCenter defaultCenter] removeObserver:self];
	
	[eventList_ removeAllObjects];
	[eventList_ release];
	//UI Control
	[eventComboBox release];
	[eventRunningLabel release];
	
	[super dealloc];
}

@synthesize EventList = eventList_;

- (NSInteger) hasEventExisted:(NSString*) eventName
{
	for(int i = 0; i < [eventList_ count]; i++)
	{
		EventItem*	event = (EventItem*)[eventList_ objectAtIndex:i];
		if([event.Name isEqualToString:eventName])
		{
			return i;
		}
	}
	
	return -1;	
}

- (EventItem*)getCurrentEvent
{
	if([eventList_ count] > 0)
	{
		int index = [self hasEventExisted:(NSString*)[eventComboBox objectValueOfSelectedItem]];
		if(index >= 0)
		{
			EventItem* item = [eventList_ objectAtIndex:index];
			return item;
		}
	}

	return nil;
}

- (EventItem*)CurrentEvent
{
	return [self getCurrentEvent];
}

- (void) updateEventRunningLabel
{
	if([self getCurrentEvent] == nil)
		[eventRunningLabel setStringValue:@"0"];
	else {
		NSString* durationString = [CommonFunc getStringFromTimeInterval:[self getCurrentEvent].Duration];
		[eventRunningLabel setStringValue:[NSString stringWithFormat:@"%@", durationString]];
		[durationString release];		
	}
}

- (void)eventChanged:(int)index
{
	if([eventComboBox indexOfSelectedItem] >= 0)
	{
		[[ProcessMonitor sharedProcMonitor] forceActiveChanged];
		[self updateEventRunningLabel];
		[[NSNotificationCenter defaultCenter] postNotificationName:@"EventChanged" object:self];	
	}
}

- (void)comboBoxSelectionDidChange:(NSNotification *)notification
{	
	[self eventChanged:[eventComboBox indexOfSelectedItem]];
}

- (void) checkEventButtonStatus
{
	if([eventList_ count] > 1)
	{
		[eventDel setEnabled:YES];
	}
	else 
	{
		[eventDel setEnabled:NO];
	}	
}

- (NSString*) validateEventName:(NSString*)eventName
{
	NSString* candidateEventName = eventName;
	if([self hasEventExisted: eventName] >= 0)
	{
		for(int i = 1; i < 10000; i++)
		{
			if([self hasEventExisted: [NSString stringWithFormat:@"%@(%d)", eventName, i]] < 0)
			{
				candidateEventName = [NSString stringWithFormat:@"%@(%d)", eventName, i];
				break;
			}
		}
	}
	
	return candidateEventName;
}

- (NSString*) createEvent:(NSString*)eventName
{	
	//check if valid
	NSString* candidateEventName = [self validateEventName:eventName];
	
	//create a new Event
	EventItem *newEvent = [[EventItem alloc] init];
	newEvent.Name = [[NSString alloc] initWithString:candidateEventName];
	
	//add to array
	[eventList_ addObject:newEvent];
	
	//add to combo list
	[eventComboBox addItemWithObjectValue:newEvent.Name];
	[eventComboBox selectItemWithObjectValue:newEvent.Name];
	 
	[[NSNotificationCenter defaultCenter] postNotificationName:@"EventCountChanged" object:self];	
	
	[newEvent release];
		
	return candidateEventName;
}

-(EventItem*)getEventByName:(NSString*)name
{
	for(EventItem* item in eventList_)
	{
		if([item.Name isEqualToString:name])
			return item;
	}
	
	return nil;
}

-(void)initEventList
{
	[self createEvent:@"Default"];
	
	//KVO
	[[ProcessMonitor sharedProcMonitor] addObserver:self forKeyPath:@"RunningTime" options:0 context:nil];
	[[SummaryController sharedController] addObserver:self forKeyPath:@"CandidateEventName" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:nil];
}

- (void)addEventHandler
{
	[self createEvent:@"Default"];
}

- (IBAction)addEventClickedAction:(id)sender
{
	[self addEventHandler];
}

- (void)delEventHandler
{
	EventItem* delItem = [self getEventByName:(NSString*)[eventComboBox objectValueOfSelectedItem]];
	int index = [eventComboBox indexOfSelectedItem];
	
	[eventComboBox removeItemAtIndex:index];
	[eventList_ removeObject:delItem];

	[eventComboBox selectItemAtIndex:(index > 0 ? index - 1 : index)];
	if(index == 0) //the before-after are both zero, means combobox will not fire selecteddidchanged
		[self eventChanged:0];
	
	[[NSNotificationCenter defaultCenter] postNotificationName:@"EventCountChanged" object:self];			
}

- (IBAction)delEventClickedAction:(id)sender
{
	[self delEventHandler];
}

- (void)ProcMonitorRunningNotification
{
	[[self getCurrentEvent] timerNotify];
	[self updateEventRunningLabel];
}

- (void)ProcMonitorActiveChanged
{
	[[self getCurrentEvent] activeChangedNotify];
	[[NSNotificationCenter defaultCenter] postNotificationName:@"RecordChanged" object:self];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
	if([keyPath isEqualToString:@"RunningTime"])
	{
		[self ProcMonitorRunningNotification];
	}
	else if([keyPath isEqualToString:@"CandidateEventName"])
	{
		NSString* newName = (NSString*)[change valueForKey:NSKeyValueChangeNewKey];
		NSString* oldName = (NSString*)[change valueForKey:NSKeyValueChangeOldKey];
		if(newName != nil && newName.length > 0 && ![newName isEqualToString:oldName])
		{
			NSString* candidateEventName = [self validateEventName:newName];
			
			NSInteger index = [eventComboBox indexOfItemWithObjectValue:oldName];
			NSInteger currentIndex = [eventComboBox indexOfSelectedItem];
			
			[eventComboBox removeItemAtIndex:index];
			[eventComboBox insertItemWithObjectValue:candidateEventName atIndex:index];
			
			EventItem* changingItem = [self getEventByName:oldName];
			[changingItem.Name release];
			changingItem.Name = [[NSString alloc] initWithString:candidateEventName];
			
			//after item removed, the index will be reset to -1
			[eventComboBox selectItemAtIndex:currentIndex];
		}
	}

	//not necessary to call super's(NSObject's) observer
	//[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}

- (IBAction)resetAction:(id)sender
{
	[[EventController sharedController].CurrentEvent reset];
	[self updateEventRunningLabel];
	[[NSNotificationCenter defaultCenter] postNotificationName:@"RecordChanged" object:self];
}

@end
